import Action from "./Action";
import {RequestMethodType} from "../../request/RequestMethod";
import {ActionMapValueType} from "./ActionMethodsBase";
import ObjectUtil from "../../utils/ObjectUtil";
import actionPool from "./ActionPool";

class ActionRegistrar {

    // 获取所有控制器
    actions() {
        return ObjectUtil.deepClone(actionPool.actionMap)
    }

    // 获取所有路由
    routes() {
        return ObjectUtil.deepClone(actionPool.routeMap)
    }

    /**
     * 构建路由
     * @param {Action} action 控制器
     */
    buildRouteMap(action: Action) {
        if (!action) return
        if (!action.routeMap || Object.keys(action.routeMap).length === 0) return;
        for (let route in action.routeMap) {
            const routeInfo = action.routeMap[route];
            if (!actionPool.routeMap.hasOwnProperty(routeInfo.method)) {
                throw new Error(`Route ${routeInfo.method} not found.`);
            }
            let path = action.path + "/" + route
            if (!path.startsWith('/')) {
                path = '/' + path
            }
            if (path.endsWith('/')) {
                path = path.replace(/\/+$/, '')
            }
            path = path.replace(/\/+/g, '/')
            if (actionPool.routeMap[routeInfo.method].hasOwnProperty(path)) {
                throw new Error(`Action ${action.name} - ${route} route is repeated!`);
            }
            actionPool.routeMap[routeInfo.method][path] = routeInfo
        }
    }

    /**
     * @param {Action[]} actions 控制器
     * @return {ActionRegistrar}
     */
    adds(actions: Action[]): ActionRegistrar {
        if (!actions || actions.length === 0) return this
        for (let action of actions) {
            if (actionPool.actionMap.hasOwnProperty(action.name)) {
                throw new Error('Action "' + action.name + '" is repeated!')
            }
            actionPool.actionMap[action.name] = action
            this.buildRouteMap(action)
        }
        return this
    }

    /**
     * 根据路径和请求方式获取路由
     * @param {string} path 路径
     * @param {RequestMethodType} method 请求方式
     * @return {ActionMapValueType|null}
     */
    get(path: string, method: RequestMethodType): ActionMapValueType | null {
        if (!method) return null;
        const methodMap = actionPool.routeMap[method]
        if (!methodMap) return null;
        const routeInfo = methodMap[path]
        if (!routeInfo) return null;
        return routeInfo
    }
}

const actionRegistrar = new ActionRegistrar()
export default actionRegistrar
